<template>
  <div class="title">
    CsTool  
  </div>
  <div class="contain">
    <el-form 
      ref="ruleFormRef"   
      class="form" 
      :model="form" 
      :rules="rules" 
      status-icon 
      label-width="30px" 
      :inline="true"
    >
      <el-form-item 
        prop="year"
      >
        <el-input-number v-model="form.year">
          <template #suffix>
            <span>年</span>
          </template>
        </el-input-number>
      </el-form-item>

      <el-form-item 
        prop="week"
      >
        <el-input-number v-model="form.week">
          <template #suffix>
            <span>周</span>
          </template>
        </el-input-number>
      </el-form-item>

      <el-form-item>
        <el-upload 
          ref="upload_11" 
          :limit="1" 
          :on-exceed="handleExceed_11" 
          :on-change="handleChange_11"
          :auto-upload="false"
        >
          <template #trigger>
            <el-button 
              class="long"
              type="primary"
            >  
              选择文件(11.csv)
            </el-button>
          </template>
        </el-upload>
      </el-form-item>

      <el-form-item>
        <el-upload 
          ref="upload_13" 
          :limit="1" 
          :on-exceed="handleExceed_13" 
          :auto-upload="false"
          :on-change="handleChange_13"
        >
          <template #trigger>
            <el-button 
              class="long"
              type="primary" 
            >
              选择文件(13.csv)
            </el-button>
          </template>
        </el-upload>
      </el-form-item>

      <el-form-item>
        <label>
          <el-button 
            class="short"
            type="primary" 
            :disabled="status.btn_create_is_disable"
            @click="onSubmit(ruleFormRef)"
          >  
            提交
          </el-button>
        </label>
        <label>
          <el-button 
            class="short"
            type="primary" 
            :disabled="status.btn_clear_is_disable"
            @click="onClear(ruleFormRef)"
          >
            重置
          </el-button>
        </label>
      </el-form-item>
    </el-form>


    <!-- move to single vue file -->
    <div class="result" 
      v-show="status.results_is_showing"
    >
      <el-descriptions 
        :column="2"
        direction="vertical"
      >
        <template #title> 
          {{ result_info }}
        </template>
        <template #extra> 
          <el-button 
            type="primary"
            :disabled="status.btn_clear_is_disable"
            @click="onClearRemoteFile()"
          >  
            <el-icon><Delete /></el-icon>
          </el-button>
        </template>
        <el-descriptions-item 
          v-for="(result, index) in results.files"
          :key="index"
          :label="result.label"
        >
          <a :href="result.url">
            {{ result.fname }} 
          </a>
        </el-descriptions-item>
      </el-descriptions>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {ref, reactive, computed, onMounted} from 'vue'
import type {FormInstance, FormRules, UploadRawFile } from 'element-plus'
import type {UploadInstance, UploadProps } from 'element-plus'
import {genFileId } from 'element-plus'
import {ElMessage } from 'element-plus'
import service from "./http"
import {Results} from './local_result.ts'
import {CalculateWeeks} from './day_of_week.ts'



interface FileItem {
  name: string
  raw: UploadRawFile
}
interface RuleForm {
  year: number
  week: number
  upload_11: FileItem
  upload_13: FileItem
}

const form = reactive<RuleForm>(
  {
    year: new Date().getFullYear(),
    week: CalculateWeeks(new Date()),
    upload_11: {
      name: '',
      raw: null as UploadRawFile
    },
    upload_13: {
      name: '',
      raw: null as UploadRawFile
    }
  }
)

const ruleFormRef = ref<FormInstance>()

const rules = reactive<FormRules<RuleForm>>({
  year: [
    {type:'integer', required: true, message:'Year between 2020 to 2050', trigger: 'change', min:2020, max:2050} ,
  ], 
  week: [
    {type:'integer', required: true, message:'Week between 1 to 53', trigger: 'change', min:1, max:53} ,
  ],
})


class UIStatus {
  private _btn_create_is_disable: boolean;
  private _btn_clear_is_disable: boolean;
  private _results_is_showing: boolean;

  constructor(){
    this._btn_create_is_disable = true;
    this._btn_clear_is_disable = false;
    this._results_is_showing = false;
  }

  public get btn_create_is_disable(): boolean{
    return this._btn_create_is_disable;
  }
  public get btn_clear_is_disable(): boolean{
    return this._btn_clear_is_disable;
  }
  public get results_is_showing(): boolean {
    return this._results_is_showing;
  }

  public enable_create(): void{
    this._btn_create_is_disable = false;
  }
  public disable_create(): void{
    this._btn_create_is_disable = true;
  }
  public enable_clear(): void{
    this._btn_clear_is_disable = false;
  }
  public disable_clear(): void{
    this._btn_clear_is_disable = true;
  }
  public show_results(): void {
    this._results_is_showing = true;
  }
  public hide_results(): void {
    this._results_is_showing = false;
  }

  private _upload_file_is_ready(upload_file_item: FileItem) : boolean{
    return upload_file_item.raw !== null;
  }
  public all_upload_files_is_ready(upload_11: FileItem, upload_13: FileItem): boolean{
    return this._upload_file_is_ready(upload_11) && this._upload_file_is_ready(upload_13);
  }
 

  private _clear_upload_file(upload_file_item) : void {
    if(upload_file_item.name !== undefined && 
      upload_file_item.name !== null && 
      upload_file_item.name.length > 0)
    {
      upload_file_item.name = '';
      upload_file_item.raw = null as UploadRawFile
    }
  }
  public clear_all_upload_files(upload_11: FileItem, upload_13: FileItem): void {
    this._clear_upload_file(upload_11);
    this._clear_upload_file(upload_13);
  }
  public upload_13_file_name_is_valid(fname: string) : boolean {
    return fname.endsWith("13.csv")
  }
  public upload_11_file_name_is_valid(fname: string) : boolean {
    return fname.endsWith("11.csv")
  }
}

const status = reactive<UIStatus>(new UIStatus());
const results = reactive<Results>(new Results())
const result_info = computed( ()=> {
  return "创建：" + results.timestamp;
})


const onSubmit = async (formEl: FormInstance | undefined) => {
  if(!formEl) return;
  await formEl.validate((valid, fields) => {
    if(valid){ 
      status.disable_create()

      const form_data = new FormData();
      form_data.append("year", form.year.toString());
      form_data.append("week", form.week.toString());
      form_data.append("files", form.upload_11.raw, form.upload_11.name);
      form_data.append("files", form.upload_13.raw, form.upload_13.name);



      //let url = "/cstool/test";
      const url = "/cstool/";
      service.post(url, 
        form_data, 
        {
          headers: {'Content-Type': 'multipart/form-data'}
        }
      )
      .then(response => {
        const ok = response["success"];
        if (ok) {
          const data = response["data"];
          const files = data["files"]

          const set_url = (fs, key) => {
            const f = fs[key]
            return "http://175.24.184.170:8000/cstool" + f.url + f.fname;
          }

          results.set_all(form.year, form.week,  {
            local_region : {
              label: "Local Region Week",
              url: set_url(files, "local_region"),
              fname: files["local_region"].fname,
            },
            sales_country_ob: {
              label: "Sales Country Week OB",
              url: set_url(files, "sales_country_ob"),
              fname:files["sales_country_ob"].fname,
            },
            sales_region_ob: {
              label: "Sales Region Week OB",
              url: set_url(files, "sales_region_ob"),
              fname:files["sales_region_ob"].fname,
            },
            trade_line: {
              label: "Trade Line Week",
              url: set_url(files, "trade_line"),
              fname:files["trade_line"].fname,
            },
            sales_country_ib: {
              label: "Sale Country Week IB",
              url: set_url(files, "sales_country_ib"),
              fname:files["sales_country_ib"].fname,
            },
            sales_region_ib: {
              label: "Sale Region Week IB",
              url:  set_url(files, "sales_region_ib"),
              fname:files["sales_region_ib"].fname,
            }
          });
          status.show_results();

          console.log("response, json:[" + JSON.stringify(response) + "]");
        } else {
          //TODO:  ElMessage
          console.log("response code failed");
        } 
        status.enable_create()
      })
      .catch(error => {
        //TODO:  ElMessage
        console.error('Got an err:', error);
        status.enable_create()
      })
      console.log("submit : ", form_data)
    } else {
        console.log('error submit', fields);
    }
  })
}

const upload_11 = ref<UploadInstance>();
const upload_13 = ref<UploadInstance>();

const clear_remote_files = () => {
  const url = "/cstool/clear";
  service.post(url)
  .then(response => {
    const ok = response["success"];
    if (ok) {
      console.log("ok: response: [" + JSON.stringify(response) + "]");
    } else {
      console.log("response code failed");
    } 
  })
  .catch(error => {
    console.error('Got an err:', error);
  })
}

const onClear = async (formEl: FormInstance | undefined) => {
  if(!formEl) return ;
  formEl.resetFields() ;

  upload_11.value!.clearFiles();
  upload_13.value!.clearFiles();

  status.clear_all_upload_files(upload_11, upload_13);

  status.hide_results();

  //clear_remote_files();
  onClearRemoteFile();
}
const onClearRemoteFile = async() => {
  clear_remote_files();
  results.clear();
}

onMounted(() => {
  clear_remote_files();
}
)

// upload file
const handleExceed_11 : UploadProps['onExceed'] = (files) => {
  upload_11.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  upload_11.value!.handleStart(file);
}
const handleChange_11 : UploadProps['onChange'] = (file): void =>  {
  if(status.upload_11_file_name_is_valid(file.name)){

    form.upload_11.name = file.name;
    form.upload_11.raw = file.raw;
    
    if(status.all_upload_files_is_ready(form.upload_11, form.upload_13)){
      status.enable_create();
    }
  }
  else{
    upload_11.value!.clearFiles();
    ElMessage( {
      message: 'Error file name:(' + file.name + '), need (*11.csv)',
      type: 'error',
    });
    console.log("Invalid file name:(%s), need (*11.csv)", file.name);
  }
}

const handleExceed_13 : UploadProps['onExceed'] = (files) => {
  upload_13.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  upload_13.value!.handleStart(file);

}
const handleChange_13 : UploadProps['onChange'] = (file): void => {
  if(status.upload_13_file_name_is_valid(file.name)){

    form.upload_13.name = file.name;
    form.upload_13.raw = file.raw;

    if(status.all_upload_files_is_ready(form.upload_11, form.upload_13)){
      status.enable_create();
    }
  }
  else{
    upload_13.value!.clearFiles();
    ElMessage( {
      message: 'Error file name:(' + file.name + '), need (*13.csv)',
      type: 'error',
    });
    console.log("Invalid file name:(%s), need (*13.csv)", file.name);
  }
}

</script>



<style>
  .contain {
    padding: 1rem;
    font-size: 1rem;
    border-radius: 7px;
    background-color: rgba(60, 60, 60, 0.12);
  }
  .form {
    width: 500px;
  }
  .form .el-input-number {
    width: 210px;
  }

  .form .short {
    width: 220px;
  }
  .form .long {
    width:200px
  }
  .form .el-upload-list__item {
    width: 200px
  }

  .result {
    padding: 1rem;
    border-radius: 6px;
    background-color: rgba(60, 60, 60, 0.29);
  }
</style>
